package com.example.util.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 情报REDIS读取工具
 *
 * @author Liujh
 * @since 2021-05-08
 */
@Component
public class CtRedisUtil {

    private  final String SEPARATE_FIELD = ",";

    private  final String SEPARATE_KEY_VALUE = ":";

    private  final String SEPARATE_KEY = "_";

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private RedisTemplate<String, String> stringRedisTemplate;

    public CtRedisUtil() {
    }

   /* public void setRedisTemplate(RedisTemplate redisTemplate) {
        CtRedisUtil.redisTemplate = redisTemplate;
    }*/
    public  boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public  List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    public  Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    public  boolean lSetAll(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().leftPushAll(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public  synchronized void hset(String key, String key1, String value) {
        value = StringUtils.isEmpty(value) ? "" : value;
        redisTemplate.opsForHash().put(key, key1, value);
    }

    public  synchronized Long hdel(String key, String key1) {
        return redisTemplate.opsForHash().delete(key, key1);
    }
    public  synchronized void set(String key, String key1) {
        redisTemplate.opsForValue().set(key, key1);
    }

    /**
     * redis结果解析成bean
     *
     * @param result      bean
     * @param redisString redis数据
     */
    public  Object getResultByRedis(Object result, String redisString) {
        if (StringUtils.isEmpty(redisString)) {
            return null;
        }
        try {
            String[] redisItems = redisString.split(SEPARATE_FIELD);
            Class resultClass = result.getClass();
            List<Field> resultFields =new ArrayList<>();
            while (resultClass != null) {
                resultFields.addAll(Arrays.asList(resultClass.getDeclaredFields()));
                resultClass = resultClass.getSuperclass();
            }
            for (Field field : resultFields) {
                field.setAccessible(true);
                for (String redisItem : redisItems) {
                    String itemKey = redisItem.split(SEPARATE_KEY_VALUE)[0];
                    String itemValue = redisItem.split(SEPARATE_KEY_VALUE).length > 1 ?
                        redisItem.split(SEPARATE_KEY_VALUE)[1] : "";
                    int separateIndex = itemKey.indexOf(SEPARATE_KEY);
                    while (separateIndex >= 1 && separateIndex != itemKey.length() - 1) {
                        itemKey = itemKey.substring(0, separateIndex)
                            + itemKey.substring(separateIndex + 1, separateIndex + 2).toUpperCase()
                            + itemKey.substring(separateIndex + 2);
                        separateIndex = itemKey.indexOf(SEPARATE_KEY);
                    }
                    if (field.getName().equals(itemKey)||("classString".equals(field.getName())&&"class".equals(itemKey))) {
                        try {
                            field.set(result, itemValue);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return result;
    }

    public void publish(String channel, String message) {
        stringRedisTemplate.convertAndSend(channel, message);
    }
}
